package us.versus.them.weeds;

import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.Lib;

import us.versus.them.weeds.constraints.Heigth;

class Weed {
	public var vertlets:Array< Vertlet >;
	public var segments:Array< Segment >;
	var heigths:Array< Heigth >;

	static var LEAF_GREEN = 0x00FF00;
	static var STALK_GREEN = 0x00AA00;
	static var FLOWER_CORE = 0xFFFF00;
	static var FLOWER_PETAL = 0xFF0000;

	public var x:Float;
	public var y:Float;
	
	public function new( x:Float, y:Float, length:Float, count:Int ) {
		this.init( x, y, length, count );
	}

	public function init( x:Float, y:Float, length:Float, count:Int ) {
		this.x = x;
		this.y = y;

		vertlets = new Array< Vertlet >();
		segments = new Array< Segment >();
		heigths = new Array< Heigth >();

		var n = if ( Math.random() < 0.5 ) 1 else -1;
		var xinc = length * n * ( 0.2 + Math.random() * 0.3 );
		var xacc = 0.0;
		var previous = null;

		for ( i in 0 ... count ) {
			var current = new Vertlet( 
				x + xacc
				, y - Math.sqrt( Math.abs( xacc * 200 ) )
				, ( count - i / count ) 
			);
			xacc += xinc;

			vertlets.push( current );

			heigths.push( new Heigth( current, 0.08 ) );

			if ( null != previous ) {
				segments.push( new Segment( previous, current ) );
			}
			previous = current;
		}
	}

	public function move( gravity:Float, ?damping:Float, ?timeStep:Float ) {
		for ( vertlet in vertlets ) {
			vertlet.force.y += gravity;
			vertlet.move( damping, timeStep );
		}
		for ( heigth in heigths ) {
			heigth.enforce();
		}
		for ( segment in segments ) {
			segment.enforce();
		}
		vertlets[ 0 ].current.x = x;
		vertlets[ 0 ].current.y = y;
	}

	public function draw( graphics:Graphics ) {
		drawStalks( graphics );
		drawLeaves( graphics );
	}

	public function drawStalks( graphics:Graphics ) {
		var act = graphics.moveTo;
		for ( vertlet in vertlets ) {
			act( vertlet.current.x, vertlet.current.y );
			graphics.lineStyle( 4, STALK_GREEN );
			act = graphics.lineTo;
		}
	}

	public function drawLeaves( graphics:Graphics ) {
		var prior : Vertlet = null;
		var n = 1;
		for ( vertlet in vertlets ) {
			if ( null != prior ) {
				drawLeaf( graphics, vertlet, prior, n == vertlets.length );
			}
			prior = vertlet;
			n++;
		}
	}

	public function drawLeaf( graphics:Graphics, vertlet:Vertlet, prior:Vertlet, isLast:Bool ) {
		var x = ( vertlet.current.x - prior.current.x );
		var y = ( vertlet.current.y - prior.current.y );
		var s = Math.sqrt( x * x + y * y );

		// about 10 pixels long (completely arbitrary number)
		if ( 0 != s ) {
			x = 10 * x / s;
			y = 10 * y / s;
		}

		graphics.lineStyle( 4, STALK_GREEN );
		graphics.moveTo( vertlet.current.x, vertlet.current.y );
		graphics.lineTo( vertlet.current.x + x , vertlet.current.y + y );

		var center_rad = 4;
		var center_x = Math.floor( vertlet.current.x + x * 8 / 5 );
		var center_y = Math.floor( vertlet.current.y + y * 8 / 5 );
		if ( isLast ) {
			center_rad = 5;
			drawFlower( graphics, 6, center_x, center_y, center_rad );
			graphics.beginFill( FLOWER_CORE );
			graphics.lineStyle( 2, FLOWER_CORE );
		} else {
			graphics.beginFill( LEAF_GREEN );
			graphics.lineStyle( 2, STALK_GREEN );
		}

		graphics.drawCircle( center_x, center_y, center_rad);
		graphics.endFill();
	}

	public function drawFlower( graphics:Graphics, slices:Int, x:Int, y:Int, rad:Int ) {
		var slices = 6;
		var flower_dist = rad * 9 / 7;
		for ( i in 0 ... slices ) {
			var angle = 44.0 / 7.0 * i / slices;
			graphics.lineStyle( 2, FLOWER_CORE );
			graphics.beginFill( FLOWER_PETAL );
			graphics.drawCircle( 
				Math.floor( x - flower_dist * Math.cos( angle ) )
				, Math.floor( y - flower_dist * Math.sin( angle ) )
				, flower_dist
			);
			graphics.endFill();
		}

	}
}
